<script>
import Search from "../Search/index.vue";
import Header from "./header.vue";
import Table from "./table.vue";
import ExcelAlert from "@/components/downloadmsg";
import siteMixin from "../../siteMixin.js";
import { cloneDeep, uniq, isEmpty, merge } from "lodash";
import { isNumber } from "xe-utils/methods";
export default {
  mixins: [siteMixin],
  props: {
    singleTable: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      formData: {},
      autoreloadTimer: null,
      firstLoad: true,
    };
  },
  provide() {
    return {
      context: {
        onSearch: this.onSearch,
        onExcel: this.onExcel,
        onExcelInfo: this.onExcelInfo,
        onFormDataUpdate: this.onFormDataUpdate,
        onAutoReload: this.onAutoReload,
      },
    };
  },
  computed: {
    headerOptions() {
      return undefined;
    },
    searchOptions() {
      return undefined;
    },
    tableOptions() {
      return undefined;
    },
    listTableOptions() {
      return undefined;
    },
    axiosConfig: {
      cache: false, // 禁用缓存
      get: function () {
        if (this.$refs.table) {
          return cloneDeep(this.$refs.table.axiosConfig);
        } else {
          return {
            currentPage: 1,
            currentPageTotal: 50,
          };
        }
      },
    },
  },
  methods: {
    onTableReload() {
      this.$refs.table.reload();
    },
    onSearch() {
      let copyFormData = this._formatValue(
        this.searchOptions.columns,
        this.formData
      );
      this.$refs.table.search(copyFormData);
    },
    onFormDataUpdate(formData) {
      for (let key in formData) {
        this.$set(this.formData, key, formData[key]);
      }
    },
    onExcel() {
      const url = this.tableOptions.pageApiPromise;
      const params = this.$refs.table.mergeRequestHandler();
      const obj = merge({ isXls: 1, xlsPage: 1 }, params[0]);
      if (window.siteHeaders.is_new_import == "1") {
        ExcelAlert({ url, obj });
      } else {
        this.$Excel($AONE_LAN.userList, url, obj);
      }
    },
    onExcelInfo() {
      const url = this.tableOptions.pageExcelInfoPromise;
      const obj = this.$refs.table.axiosConfig;
      if (window.siteHeaders.is_new_import == "1") {
        ExcelAlert({ url, obj });
      } else {
        this.$Excel($AONE_LAN.userInfo, url, obj);
      }
    },
    onAutoReload(sec) {
      if (!sec) {
        return clearInterval(this.autoreloadTimer);
      }
      if (this.autoreloadTimer) {
        clearInterval(this.autoreloadTimer);
      }
      this.autoreloadTimer = setInterval(() => {
        this.$refs.table.reset();
      }, Number(sec) * 1000);
    },
    compareCheckQuery() {
      const { query = {} } = this.$route || {};
      if (isEmpty(query)) return;
      const formatQuery = this.beforeFormatQuery(query);
      // 如果formData中有值比较query中参数
      const formDataKeys = Object.keys(this.formData).filter(
        (key) => this.formData[key] !== undefined
      );
      const queryKeys = Object.keys(formatQuery).filter(
        (key) => formatQuery[key] !== undefined
      );
      // 判断是否需要从url中替换参数
      let isNeedCheck = uniq(formDataKeys.concat(queryKeys)).some((key) => {
        // 处理value数组
        if (
          Array.isArray(this.formData[key]) &&
          formatQuery[key] &&
          (this.formData[key].length != 1 ||
            (this.formData[key].length == 1 &&
              this.formData[key][0] != formatQuery[key]))
        ) {
          return true;
        }
        // 处理value非数组
        else if (
          !Array.isArray(this.formData[key]) &&
          this.formData[key] != formatQuery[key]
        ) {
          return true;
        }
        return false;
      });
      // 如果有不一样，则用query的参数，覆盖formData的参数
      if (isNeedCheck) {
        for (let key in this.formData) {
          if (
            Reflect.has(formatQuery, key) &&
            Array.isArray(this.formData[key])
          ) {
            this.formData[key] = [`${formatQuery[key]}`]; // 下拉框统一用字符串
          } else if (Reflect.has(formatQuery, key)) {
            this.formData[key] = `${formatQuery[key]}`; // 都转字符串
          } else if (Array.isArray(this.formData[key])) {
            this.formData[key] = this.formData[key] ?? [];
          } else {
            this.formData[key] = this.formData[key] ?? undefined;
          }
        }
      }
      // 如果上面数据没变化，继续比较钩子里面是否变化
      const oldFormData = cloneDeep(this.formData);
      this.compareQuery(formatQuery, this.formData);
      if (!isNeedCheck) {
        isNeedCheck = uniq(
          Object.keys(oldFormData).concat(Object.keys(this.formData))
        ).some((key2) => {
          if (
            Array.isArray(oldFormData[key2]) &&
            Array.isArray(this.formData[key2]) &&
            oldFormData[key2].length == 0 &&
            this.formData[key2].length == 0
          ) {
            return false;
          }
          return oldFormData[key2] != this.formData[key2];
        });
      }
      if (isNeedCheck) {
        this.$refs.search.formData = this.formData;
      }
      return isNeedCheck;
    },
    // 兼容老页面
    beforeFormatQuery(query) {
      const formatQuery = cloneDeep(query);
      const searchColumns = this.$refs.search.formOptions.columns;
      // 处理路由参数别名，比如组件叫user_name,但是路由传的名称是userName,看queryAlias参数
      searchColumns.forEach((it) => {
        if (Array.isArray(it.queryAlias)) {
          it.queryAlias.forEach((alias) => {
            if (formatQuery[alias]) {
              formatQuery[it.prop] = formatQuery[alias];
            }
          });
        }
      });
      // 处理路由参数小驼峰，比如路由参数中有userAccount满足小驼峰格式，自动增加下划线字段
      Object.keys(formatQuery).forEach((key) => {
        const newKey = key.replace(/[A-Z]/g, function (a) {
          return "_" + a.toLowerCase();
        });
        formatQuery[newKey] = formatQuery[key];
      });

      // 日期基本转换
      // 满足条件：
      // 1、url中参数是date
      ///// 其中：若date是数字，则1是今日等类推；若date是非数字，则是日期中文或英文；若date还可能是时间范围如2023-02-01 00:00:00 - 2023-02-05 23:59:59
      // 2、优先级判断：当前页面有selectday组件且有组件有defaulQuery:true属性;当前页面只有一个selectday组件；或者存在多个selectday组件时，只有一个有默认value值也可
      // 那么就转换date参数到日期组件
      if (formatQuery.date) {
        const selectdayComs = searchColumns.filter(
          (it) => it.comtype == "selectday"
        );
        const defaultComs = selectdayComs.filter((it) => it.defaulQuery);
        const multipleComs = selectdayComs.filter((it) => it.value);
        let needChangeComs = [];
        // 优先级
        if (defaultComs.length > 0) {
          // 当前页面有selectday组件且有组件有defaulQuery
          needChangeComs = defaultComs;
        } else if (selectdayComs.length == 1) {
          // 当前页面只有一个selectday组件
          needChangeComs = [selectdayComs[0]];
        } else if (multipleComs.length == 1) {
          // 存在多个selectday组件时，只有一个有默认value值也可
          needChangeComs = [multipleComs[0]];
        }
        if (needChangeComs.length) {
          needChangeComs.forEach((singleCom) => {
            if (/^\d+$/.test(formatQuery.date)) {
              formatQuery[singleCom.prop] = formatQuery.date;
            } else {
              this.$tool.defaultTime(
                formatQuery,
                formatQuery.date,
                singleCom.startTimeField,
                singleCom.endTimeField,
                singleCom.prop
              );
            }
          });
          delete formatQuery.date;
        }
      }
      return formatQuery;
    },
    // 自定义恢复缓存时钩子
    compareQuery(query, formData) {},
    // 渲染多个表格
    renderListTable() {
      if (this.listTableOptions !== undefined) {
        const tables = [];
        for (let i = 0; i < this.listTableOptions.length; i++) {
          tables.push(
            <Table
              ref={"listTable" + i}
              class="page-table"
              tableOptions={this.listTableOptions[i]}
            />
          );
        }
        return <div ref="listTables">{tables}</div>;
      }
    },
  },
  mounted() {
    const isNeedCheck = this.compareCheckQuery();
    if (this.tableOptions.loadImmediate !== false || isNeedCheck) {
      // beforeFirstMountedSearch 钩子
      this.beforeFirstMountedSearch && this.beforeFirstMountedSearch();
      this.$refs.table.search(this.formData);
    }
    this.$nextTick(() => {
      this.tableOptions.loadImmediate = true;
      this.firstLoad = false;
    });
  },
  activated() {
    const isNeedCheck = this.compareCheckQuery();
    if (this.firstLoad && !isNeedCheck) return;
    if (isNeedCheck) {
      // beforeFirstMountedSearch 钩子
      this.beforeFirstMountedSearch && this.beforeFirstMountedSearch();
      this.$refs.table.search(this.formData);
    }
  },
  beforeDestroy() {
    if (this.autoreloadTimer) {
      clearInterval(this.autoreloadTimer);
    }
  },
  render(h) {
    return (
      <div
        class={{
          "aone-page": true,
          "aone-table-single": this.singleTable,
          ["aone-page-" + this.$options.name]: this.$options.name,
          "flex-column": true,
          "aone-page-useVirtual": this.tableOptions.useVirtual,
          "aone-page-hideheaderbg": this.tableOptions.hideHeaderBg,
        }}
      >
        {this.vif(this.headerOptions !== undefined)(
          <Header
            ref="header"
            headerOptions={this.headerOptions}
            onTableReload={this.onTableReload}
          />
        )}
        {this.vif(this.searchOptions !== undefined)(
          <Search
            ref="search"
            searchOptions={this.searchOptions}
            onFormDataUpdate={this.onFormDataUpdate}
          />
        )}
        {this.vif(this.customOptions !== undefined)(
          <div ref="custom" style="display: none">
            <Table
              ref="customTable"
              class="page-table"
              tableOptions={this.customOptions}
            />
          </div>
        )}
        <Table
          ref="table"
          class="page-table"
          tableOptions={this.tableOptions}
        />
        {this.renderListTable()}
      </div>
    );
  },
};
</script>
<style scoped lang="scss">
.aone-page {
  height: calc(100vh - 91px) !important;
}
.aone-table-single {
  height: initial !important;
  /deep/ .gundong_icon {
    display: none;
  }
}
</style>
